#include "global.h"


//=======================================================================================
//
//     Module that control HD44780 based LCD  through 3 wires 
//      using 74HC164 shift regicter
//		
//		W1 W2 used like Dout And Clock, after bit D0 of the LCD data send
//		W1 became a R/S signal that no clocked
//
//		W3 used like E signal of the LCD//
//
//=======================================================================================

//---------------------------------------------------------------------------------------
//					P r i v a t e  V a r i a b l e s     D e c l a r a t i o n
//---------------------------------------------------------------------------------------

unsigned char LCD3PIN_tick;

//---------------------------------------------------------------------------------------
//					P u b l i c   V a r i a b l e s   D e c l a r a t i o n
//---------------------------------------------------------------------------------------



//---------------------------------------------------------------------------------------
//					P r i v a t e   p r o t o t y p e s
//---------------------------------------------------------------------------------------

void WriteLCD(unsigned char rs, unsigned char character);


//=======================================================================================
// 								F U N C T I O N S
//=======================================================================================

void SetTickLCD(void)  // this function uses only in interrupt to create a counted semaphore
{	
	if ((LCD3PIN_tick+=1)>10)LCD3PIN_tick=10;
};



void WriteLCD(unsigned char rs, unsigned char shifter)
{	
	unsigned char counter=0;
	
	WE=0;
	WData =0;
	counter=8;
	while(counter)
	{
		counter-=1;
		WE=0;
		if (shifter & 0b10000000)
		{
			WData =1;
		}
		else
		{
			WData =0;
		};
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");		
		WClock=1;
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		shifter=(shifter<<1); //  here may be needed adjustment regarding direction
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		WClock=0;
	}
	WData=rs;
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
	WE=1;
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
	WE=0;	

};


void InitLCD(void)
{ unsigned char count;
//	ADCON1=0b11001110;   // must be cheked
	LCD_PORT&=PORT_MASK;
	LCD_TRIS&=PORT_MASK;
	LCD3PIN_tick=0;
//===========================

//	WriteLCD(0,0xF0);

//===========================


	count=40;
	while(count)
	{
		if (LCD3PIN_tick)
		{	
			LCD3PIN_tick=0;
			count-=1;
		};
	}; // here we are waiting 40mS after power on

	WriteLCD(0,0x30);	// first init word

	count=6;
	while(count)
	{
		if (LCD3PIN_tick)
		{	
			LCD3PIN_tick=0;
			count-=1;
		};
	}; // here we are waiting 6mS

	WriteLCD(0,0x30);	//  second init word

	count=50;
	while(count) count-=1;  // 50 *2 = 100uS delay on 4MHZ quartz
	WriteLCD(0,0x30);	// third init word

	count=50;
	while(count) count-=1;  // 50 *2 = 100uS delay on 4MHZ quartz
	WriteLCD(0,0x30);	// third init word

	count=50;
	while(count) count-=1;  // 50 *2 = 100uS delay on 4MHZ quartz
	WriteLCD(0,0x38);	//  2 lines  5*8 CHARACTER SET
//	WriteLCD(0,0x34);	//  1 lines  5*8 CHARACTER SET

	count=50;
	while(count) count-=1;  // 50 *2 = 100uS delay on 4MHZ quartz
	WriteLCD(0,0x01);	//  Clear DRAM


	count=4;
	while(count)
	{
		if (LCD3PIN_tick)
		{	
			LCD3PIN_tick=0;
			count-=1;
		};
	}; // here we are waiting 4mS
	count=50;
	while(count) count-=1;  // 50 *2 = 100uS delay on 4MHZ quartz
	WriteLCD(0,0x06);	//  cursor moves in increment

	count=50;
	while(count) count-=1;  // 50 *2 = 100uS delay on 4MHZ quartz
	WriteLCD(0,0x0f);		// Display On, Cursor On
	
};


void ClearLCD(void)
{	unsigned char count;
	WriteLCD(0,0x01);
	count=4;
	while(count)
	{
		if (LCD3PIN_tick)
		{	
			LCD3PIN_tick=0;
			count-=1;
		};
	}; // here we are waiting 4mS	

};



#ifdef TwoLines
	#undef FourLines
	void WriteToPosLCD( char line, char pos)                  
	{	unsigned char count;
		if (1 == line ) WriteLCD(0,0x80+pos);
		if (2 == line ) WriteLCD(0,0xC0+pos);

		count=4;
		while(count)
		{
			if (LCD3PIN_tick)
			{	
				LCD3PIN_tick=0;
				count-=1;
			};
		}; // here we are waiting 4mS

	} 
#endif

#ifdef FourLines
	#undef TwoLines
	void WriteToPosLCD( char line, char pos)                  
		{	unsigned char count;
			if (1 == line) WriteLCD(0,0x80+pos);
			if (2 == line) WriteLCD(0,0xC0+pos);
			if (3 == line) WriteLCD(0,0x94+pos);
			if (4 == line) WriteLCD(0,0xD4+pos);
			count=4;
			while(count)
			{
				if (LCD3PIN_tick)
				{	
					LCD3PIN_tick=0;
					count-=1;
				};
			}; // here we are waiting 4mS
		} 
#endif

/*
void WriteToPosLCD(char pos)                  
		{	unsigned char count;
			count=50;
			while(count) count-=1;  // 50 *2 = 100uS delay on 4MHZ quartz
			WriteLCD(0,0x80+pos);
			count=50;
			while(count) count-=1;  // 50 *2 = 100uS delay on 4MHZ quartz
			
		};
*/
void SetLCDDim(unsigned char lines, unsigned char chars)
{	
};

void PutStrLCD( const char *ptr)
	{
 	 do{ WriteLCD(1,*ptr);
		ptr++;
		} while (*ptr);
	};


void putch(unsigned char character)
{
	WriteLCD(1,character);
};


void CursorBlinkLCD(void)
{
	WriteLCD(0,0x0f);
};

void CursorOnLCD(void)
{
	WriteLCD(0,0x0E);
};


void CursorOffLCD(void)
{
	WriteLCD(0,0x0C);
};
